--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--[[

    空手时（跑步状态下），右键发动安魂仪式：
    胡桃激发强烈的引魂火冲撞净化怪物，消耗上限2/7的理智值（消耗理智记为S）和21点体力，向鼠标悬停方向突进一小段距离（冲撞动作，具体用哪个到时候再说），撞击落点附近小范围敌人，造成7点物理伤害和大量位面伤害Z，并为胡桃回复造成总伤害7%的生命。若当前处于奔跑状态，则伤害范围扩大。
    该位面伤害的计算公式为：Z=S*火伤系数*攻击系数*移动系数
    命中的目标如果身上有血梅香效果，则会触发一次血梅香伤害同时刷新持续时间。
    之后，所有被命中的怪物类敌人会受到一次判定，若其当前血量低于胡桃当前的理智值，则有1-（x/y）^2 的概率（y为胡桃当前理智，x为怪物当前血量）被秒杀，秒杀成功的每个单位附近会出现“怨鬼尽散！”/“安息吧！”字样。若目标为梦魇类/僵尸类怪物，则判定时理智值y按双倍计算（此时只要理智值的两倍大于目标当前血量即可触发判定）。
    理智或体力不足消耗时均无法发动
    *开启【多多益善】后，被判定秒杀的怪物有概率会额外掉落一份【幽幽大行军】，概率为怪物血量上限/2000，最多为1.
    *开启【血之灶火】后，血量低于50%时，生命回复量变为造成伤害的21%，血量低于25%时，生命回复量变成造成伤害的28%。

    shadowstrike_slash_fx
    shadowstrike_slash2_fx
    chester_transform_fx
]]--
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---
    local PHYSICAL_POWER_COST = TUNING.HUTAO_DEBUGGING_MODE and 5 or 21
    local AOE_SPELL_RADIUS = 7
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 目标扫描TAGS
    local BOUNCE_MUST_TAGS = { "_combat" }
    local BOUNCE_NO_TAGS = { "INLIMBO", "wall", "notarget", "player", "companion", "flight", "invisible", "noattack", "hiding" } -- "player", "companion", "flight", "invisible", "noattack", "hiding"
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 消耗
    local function sanity_dodelta(inst,value,...)
        if inst.components.hutao_com_healing_grove then
            inst.components.hutao_com_healing_grove:SanityDoDelta(value,...)
        else
            inst.components.sanity:DoDelta(value,...)
        end
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 创建临时武器、特效
    local function CreateWeapon(planar_dmg)
        local inst = CreateEntity()
        inst.entity:AddTransform()
        inst:AddTag("weapon")
        inst:AddTag("nosteal")
        inst:AddComponent("weapon")
        inst.components.weapon:SetDamage(7)
        inst.components.weapon:SetRange(100)
        inst:AddComponent("inventoryitem")
        inst.persists = false
        inst.components.inventoryitem:SetOnDroppedFn(inst.Remove)
        inst:AddComponent("equippable")
        inst:AddComponent("planardamage")
	    inst.components.planardamage:SetBaseDamage(planar_dmg)
        return inst
    end
    local function SpawnDamageFx(x,y,z,player)
        if x and y and z then
            SpawnPrefab("chester_transform_fx").Transform:SetPosition(x,y,z)
        end
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 单个目标执行伤害
    local function DoDamage(inst,target,weapon)
        -- print("DoDamage",target)
        ----------------------------------------------
        --- 血量记录
            local target_health_old = target.components.health.currenthealth
        ----------------------------------------------
        --- 使用武器造成伤害（虚拟位面伤害）
            local planar_damage = weapon.components.planardamage:GetDamage()
            if planar_damage <= 0 then
                return
            end
            SpawnDamageFx(target.Transform:GetWorldPosition())
            target.components.combat:GetAttacked(inst, 7, weapon, nil, {
                ["planar"] = planar_damage
            })
        ----------------------------------------------
        --- 血量记录
            local target_health_new = target.components.health.currenthealth
        ----------------------------------------------
        --- 命中的目标如果身上有血梅香效果，则会触发一次血梅香伤害同时刷新持续时间。
            local has_debuff,debuff_inst = inst.components.hutao_com_blood_plum_scent_for_player:HasDebuff(target)
            if has_debuff and debuff_inst then
                debuff_inst.components.hutao_com_blood_plum_scent_for_debuff:DoDamage()
                debuff_inst.components.hutao_com_blood_plum_scent_for_debuff:ResetRemainTime()
            end
        ----------------------------------------------
        ---
            return target_health_new - target_health_old
        ----------------------------------------------
    end
    local function DoDamageAfterBaseAOE(inst,target)
        -- print("DoDamageAfterBaseAOE",target)
        ----------------------------------------------
        --[[
            之后，所有被命中的怪物类敌人会受到一次判定，若其当前血量低于胡桃当前的理智值，则有1-（x/y)^2 的概率
            （y为胡桃当前理智，x为怪物当前血量）被秒杀，秒杀成功的每个单位附近会出现“怨鬼尽散！”/“安息吧！”字样。
            若目标为梦魇类/僵尸类怪物，则判定时理智值y按双倍计算（此时只要理智值的两倍大于目标当前血量即可触发判定）。            
        ]]--
        ----------------------------------------------
        ---
            if TUNING.HUTAO_DEBUGGING_MODE then
                inst.components.hutao_com_blood_plum_scent_for_player:HitTarget(target)
            end
        ----------------------------------------------
        ---
            local player_sanity = inst.components.sanity.current
            if player_sanity <= 0 then
                return
            end
        ----------------------------------------------
        --- 
            local target_health = target.components.health.currenthealth
            if target_health <= 0 or target_health >= player_sanity then
                return
            end
        ----------------------------------------------
        --- 概率
            local x = target_health
            local y = player_sanity
            if target:HasOneOfTags("shadowcreature","shadow","shadow_aligned") then
                y = y * 2
            end
            local probability = 1 - math.pow(x/y,2)
        ----------------------------------------------
        --- 判定
            if math.random() > probability then
                --- 判定失败
                return
            end
        ----------------------------------------------
        --- 丢物品
            --*开启【多多益善】后，被判定秒杀的怪物有概率会额外掉落一份【幽幽大行军】，概率为怪物血量上限/2000，最多为1.
            if inst.components.hutao_com_talent_tree:IsUnlocked("the_more_the_better") and target.components.lootdropper then
                local target_max_health = target.components.health.maxhealth
                if math.random() < math.clamp(target_max_health/2000,0,1) then
                    target.components.lootdropper:SpawnLootPrefab("hutao_cooked_food_ghostly_march")
                end
            end
        ----------------------------------------------
        --- 执行秒杀
            target.components.health:Kill()
        ----------------------------------------------
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 技能释放检查
    local function Spell_Test_Fn(inst)
        if inst.replica.hutao_com_physical_power:GetCurrent() < PHYSICAL_POWER_COST then
            return false
        end
        if inst.replica.sanity:GetCurrent() <= 0 then
            return false
        end
        return true
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---
    local function replica_init(inst,replica)
        replica:SetTestFn(Spell_Test_Fn)
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---
    local function spell_aoe_fn(inst,pt)
        local targets = TheSim:FindEntities(pt.x,0, pt.z,AOE_SPELL_RADIUS, BOUNCE_MUST_TAGS, BOUNCE_NO_TAGS, nil)
        -----------------------------------------------------
        ---
            inst:PushEvent("hutao_event.spell_finish_for_plum_blossom",{
                pt = pt,
                radius = AOE_SPELL_RADIUS,
                spell = "requiem_ceremony",
            })
        -----------------------------------------------------
        if #targets == 0 then
            return
        end
        -----------------------------------------------------
        -- 消耗体力
            inst.components.hutao_com_physical_power:DoDelta(-PHYSICAL_POWER_COST)
        -----------------------------------------------------
        -- 消耗上限2/7的理智值（消耗理智记为S）.该位面伤害的计算公式为：Z=S*火伤系数*攻击系数*移动系数
            local max_sanity = inst.components.sanity.max
            local current_sanity = inst.components.sanity.current
            local s = math.min(max_sanity*2/7,current_sanity)
            -- inst.components.sanity:DoDelta(-s,true)
            sanity_dodelta(inst,-s,true)
        -----------------------------------------------------
        --- 
            local fire_dmg_mult = inst.components.hutao_com_fire_damage:GetAdditiveMultipliers()
            local attack_dmg_mult = inst.components.combat.externaldamagemultipliers:Get()
            local move_speed_mult = inst.components.locomotor:GetSpeedMultiplier()
        -----------------------------------------------------
        --- 最终位面伤害
            local ret_planar_damage = s*fire_dmg_mult*attack_dmg_mult*move_speed_mult
        -----------------------------------------------------
        --- 创建虚拟武器
            local weapon = CreateWeapon(ret_planar_damage)
        -----------------------------------------------------
        --- 造成伤害
            local all_health_delta_value = 0 -- 记录总目标血量变化（负数）
            for k, temp_target in pairs(targets) do
                if temp_target and temp_target:IsValid() and temp_target.components.health and not temp_target.components.health:IsDead() then
                    local temp_delta_value = DoDamage(inst,temp_target,weapon) or 0
                    all_health_delta_value = all_health_delta_value + temp_delta_value
                end
            end
            weapon:Remove()
        -----------------------------------------------------
        --- 玩家回血。胡桃回复造成总伤害7%的生命。
            -- *开启【血之灶火】后，血量低于50%时，生命回复量变为造成伤害的21%，血量低于25%时，生命回复量变成造成伤害的28%。
            local percent_for_heal = 0.07
            if inst.components.hutao_com_talent_tree:IsUnlocked("blood_hearth_fire") then
                local player_current_health_percent = inst.components.health:GetPercent()
                if player_current_health_percent < 0.5 then
                    percent_for_heal = 0.21
                elseif player_current_health_percent < 0.25 then
                    percent_for_heal = 0.28
                end
            end
            local heal_value = math.abs(all_health_delta_value)*percent_for_heal
            inst.components.health:DoDelta(heal_value)
        -----------------------------------------------------
        --- 后续判定
            for k, temp_target in pairs(targets) do
                if temp_target and temp_target:IsValid() and temp_target.components.health and not temp_target.components.health:IsDead() then
                    DoDamageAfterBaseAOE(inst,temp_target)
                end
            end
        -----------------------------------------------------
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

return function(inst)
    inst:ListenForEvent("HUTAO_OnEntityReplicated.hutao_com_requiem_ceremony",replica_init)
    if not TheWorld.ismastersim then
        return
    end
    inst:AddComponent("hutao_com_requiem_ceremony")
    inst.components.hutao_com_requiem_ceremony:SetAoeFn(spell_aoe_fn)
end